package mn.more.foundation.web;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.List;
import java.util.Map;

/**
 * @author $Author: mikeliucc $
 * @version $Id: SnoopUtil.java 5 2008-09-01 12:08:42Z mikeliucc $
 */
final class SnoopUtil {

	private SnoopUtil() { }

	static StringBuilder createHtmlHeader(StringBuilder sb,
	                                      String title,
	                                      String ccs,
	                                      String js) {
		sb.append("<HTML>");
		sb.append("<HEAD>");
		sb.append("<TITLE>").append(title).append("</TITLE>");
		if (ccs != null) {
			sb.append("<link rel=\"stylesheet\" type=\"text/css\" href='")
				.append(ccs).append("'/>");
		}
		if (js != null) {
			sb.append("<script language=\"Javascript\" src=\"").append(js)
				.append("\"></script>");
		}
		sb.append("</HEAD>");
		sb.append("<BODY>");
		sb.append("<h1>").append(title).append("</h1>");
		return sb;
	}

	static StringBuilder createHtmlFooter(StringBuilder sb) {
		sb.append(
			"<div class=\"footer\">The information rendered here is strictly used for diagnostic purposes.</div>");
		sb.append("</body>");
		sb.append("</html>");
		return sb;
	}

	static void addCellRow(StringBuilder sb, Object key, Object... values) {
		sb.append("<tr>");
		sb.append("<th>").append(key).append("</th>");
		sb.append("<td>");
		for (Object v : values) {
			if (v == null) {
				sb.append("&lt;none&gt;");
				continue;
			}
			String vstr = v.toString();
			if (vstr.trim().length() < 1) {
				sb.append("&lt;none&gt;");
			} else {
				sb.append(toString(v));
			}
			sb.append("<br/>");
		}
		sb.append("</td>");
		sb.append("</tr>");
	}

	static void addNoDataCell(StringBuilder sb) {
		sb.append("<tr><td colspan=\"2\" class=\"nodata\">NO DATA</td></tr>");
	}

	static void addTitle(StringBuilder sb, String title) {
		sb.append("<h2 onclick=\"return toggleDetail(this);\">").append(title)
			.append("</h2>");
	}

	static void startTable(StringBuilder sb) {
		sb.append(
			"<table cellspacing=\"0\" cellpadding=\"0\" class=\"report_table\" style=\"display: none;\">");
	}

	static void endTable(StringBuilder sb) {
		sb.append("</table><br/>");
	}

	static StringBuilder getServerFile(String[] filePaths) {
		StringBuilder result = new StringBuilder();
		File file = null;
		FileReader reader = null;
		try {
			for (String filepath : filePaths) {
				file = new File(filepath);
				if (file.exists()) {
					result.append("Location: ").append(filepath)
						.append("<br/>");
					if (file.canRead()) {
						reader = new FileReader(file);
						char[] data = new char[(int) file.length()];
						reader.read(data, 0, (int) file.length());
						String text = String.valueOf(data);
						result.append("<textarea rows=\"20\" cols=\"120\">").
							append(text.replaceAll("\\<", "\\&lt;")).
							append("</textarea>");
						break;
					} else {
						result.append("File is not readable.");
					}
				}
			}
		} catch (Throwable e) {
			// better to catch all possible errors for diagnostic purposes,
			// since we don't known what to expect on a remote server
			result.append(e.getMessage());
		} finally {
			if (reader != null) {
				try { reader.close(); } catch (IOException e1) {
					result.append(e1.getMessage());
				}
			}
		}

		return result;
	}

	static String toString(Object value) {
		if (value == null) { return null; }

		if (value.getClass().isArray()) {
			int length = Array.getLength(value);
			StringBuilder builder = new StringBuilder("Array: [<code>");
			for (int i = 0; i < length; i++) {
				builder.append(Array.get(value, i)).append("; ");
			}
			builder.append("</code>]");
			return builder.toString();
		}

		if (value.getClass().isAssignableFrom(List.class)) {
			List l = (List) value;
			StringBuilder buf = new StringBuilder("List: [<code>");
			for (Object aL : l) { buf.append(aL).append("; "); }
			buf.append("</code>]");
			return buf.toString();
		}

		if (value.getClass().isAssignableFrom(Map.class)) {
			Map m = (Map) value;
			StringBuilder buf = new StringBuilder("Map: [<code>");
			Object[] keys = m.keySet().toArray();
			for (Object key : keys) {
				buf.append(key).append("=").append(m.get(key)).append("; ");
			}
			buf.append("</code>]");
			return buf.toString();
		}

		//return value.toString().replaceAll(";", "<br/>").replaceAll(":", "<br/>");
		return value.toString().replaceAll(":", "<br/>");
	}
}
